#pragma once

#include "RunnableThread.h"
#include "TaskGraph.h"
#include "LockFreeQueue.h"
#include "../Memory/MallocExclusive.h"

/**
 *	TaskThread
 *	A class for managing a named thread.
 */


class TaskThread : public Runnable
{
public:

	TaskThread();

	/** Virtual destructor */
	virtual ~TaskThread() { }

	virtual uint32 Setup(const TCHAR* threadName, ThreadPriority threadPriority);

	virtual void Kill();

	virtual bool Init() override;

	virtual void Stop() override;

	virtual void Exit() override;

	/** Used for named threads to start processing tasks until the thread is idle and RequestQuit has been called. **/
	virtual void ProcessTasksUntilReturn();

	/**
	 *	Queue a task, assuming that this thread is the same as the current thread.
	 *	For named threads, these go directly into the private queue.
	 *	@param QueueIndex, Queue to enqueue for
	 *	@param Task Task to queue.
	 **/
	virtual void EnqueueTask(BaseGraphTask* task);

	// Calls meant to be called from any thread.

	/**
	 *	Will cause the thread to return to the caller when it becomes idle. Used to return from ProcessTasksUntilQuit for named threads or to shut down unnamed threads.
	 *	CAUTION: This will not work under arbitrary circumstances. For example you should not attempt to stop unnamed threads unless they are known to be idle.
	 *	Return requests for named threads should be submitted from that named thread as FReturnGraphTask does.
	 *	@param QueueIndex, Queue to request quit from
	**/
	virtual void RequestReturn();

protected:

	/** RunnableThread for this runnable  **/
	RunnableThread* mThread;
	// the alone memory chest for the thread
	MallocExclusive* mMalloc;
	/** Indicates we executed a return task, so break out of the processing loop. **/
	bool mQuitForReturn;
	/** LOFO task to execute **/
	LockFreeQueue<BaseGraphTask> mQueueTasks;

};